%define _EXCEPTION_ROUTINES_EXTERN_OR_GLOBAL_ 1 
%include"../include/exception_routines.mac" 

;actual call routines for exception or trap handling  
[section .text] 
;macro for printing error message of exceptions  
	;input:error message.if no input,default is unknown_msg 
	%macro PRINT_ERROR_MSG 0-1 unknown_msg 
		push ebp 
		mov ebp,esp 

		;print error message 
		push dword[ebp+12] ;error code  
		push dword[ebp+8] ;error address  
		push %1 ;error message  
		call print_intr_error_msg 

		pop ebp 
		ret 8 
	%endmacro 

;print routines for exception or trap  handler 
;input: 
;	1.error code; 
;	2.error address; 
;	3.error message address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|error message | 
;|eip			| 

;|ebp			| 
print_intr_error_msg:  
	push ebp 
	mov ebp,esp 
	push eax 

	;(0,0) position:show error  message 
	push 0 
	push 0 
	mov eax,[ebp+4] 
	push eax 
	call show_string_with_null 

	;(0,1) position:show error code  
	push 0 
	push 1 
	push error_code_str 
	call show_string_with_null  

	;(0,2) position:show error address  
	push 0 
	push 2 
	push eip_addr_str 
	call show_string_with_null 

	pop eax 
	pop ebp 
	ret 12 ;clean up stack 

;int 0 
;input: 
;	1.error code;  
;	2.error address. 

;Stack frame. 
;|error code	| 
;|error_addr	| 
;|eip			| 

;|ebp| 

handle_divide_error: 
	PRINT_ERROR_MSG divide_error_msg  

;int 1
;input: 
;	1.error code; 
;	2.error address. 
;output: none. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			|  
handle_debug_exception: 
	PRINT_ERROR_MSG debug_msg 
	
;int 2 
;input: 
;	1.error code; 
;	2.error address. 
;output: none. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 

handle_nmi_intr: 
	PRINT_ERROR_MSG nmi_msg   

;int 3 
;input:
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_breakpoint: 
	PRINT_ERROR_MSG breakpoint_msg  

;int 4 
;input:
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_overflow: 
	PRINT_ERROR_MSG overflow_msg  

;int 5 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			|  
handle_bound_range_exceeded: 
	PRINT_ERROR_MSG  bound_range_exceeded_msg 
	
;int 6 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_invalid_opcode: 
	PRINT_ERROR_MSG invalid_opcode_msg 

;int 7 
;input: 
;	1.error code;  
;	2.error address.  

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			|  
handle_device_not_available: 
	PRINT_ERROR_MSG device_not_available_msg 

;int 8 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
handle_double_fault: 
	PRINT_ERROR_MSG double_fault_msg  

;int 9 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_coprocessor_seg_overrun: 
	PRINT_ERROR_MSG coprocessor_seg_overrun_msg  

;int 10 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_invalid_tss:	 
	PRINT_ERROR_MSG invalid_tss_msg 

;int 11 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_segment_not_present: 
	PRINT_ERROR_MSG seg_not_present_msg  

;int 12
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_stack_fault: 
	PRINT_ERROR_MSG stack_fault_msg  
	
;int 13 
;input: 
;	1.error code; 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	|  
;|eip			| 

;|ebp			| 
handle_general_protection: 
	PRINT_ERROR_MSG general_protection_msg  

;int 14 
;input: 
;	1.error code; 
;	2.error address. 

;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_page_fault: 
	PRINT_ERROR_MSG page_fault_msg  

;int 16 
;input: 
;	1.error code; 
;	2.error address; 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error	address	| 
;|eip			| 

;|ebp			| 
handle_x87_fpu: 
	PRINT_ERROR_MSG x87_fpu_error_msg 
	
;int 17  
;input: 
;	1.error code 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_alignment_check: 
	PRINT_ERROR_MSG alignment_check_msg  
	
;int 18  
;input: 
;	1.error code 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_machine_check: 
	PRINT_ERROR_MSG machine_check_msg 

;int 19   
;input: 
;	1.error code 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_simd: 
	PRINT_ERROR_MSG simd_msg  

;reserved,set to default  
;input: 
;	1.error code 
;	2.error address. 

;Used only for near call 
;Stack frame: 
;|error code	| 
;|error address	| 
;|eip			| 

;|ebp			| 
handle_reserved: 
	PRINT_ERROR_MSG unknown_msg  


[section .data] 
	;error message 
	divide_error_msg:db 'Divide Error!',0  
	debug_msg:db 'Debug Exception!',0 
	nmi_msg:db 'NMI Interrupt!',0   
	breakpoint_msg:db 'Breakpoint Exception!',0  
	overflow_msg:db 'Overflow Exception!',0  
	bound_range_exceeded_msg:db 'BOUND Range Exceeded Exception!',0 
	invalid_opcode_msg:db 'Invalid Opcode Exception!',0 
	device_not_available_msg:db 'Device Not Available Exception!',0 
	double_fault_msg:db 'Double Fault Exception!',0 
	coprocessor_seg_overrun_msg:db 'Coprocessor Segment Overrun!',0 
	invalid_tss_msg:db 'Invalid TSS Exception!',0 
	seg_not_present_msg:db 'Segment Not Present!',0 
	stack_fault_msg:db 'Stack Fault Exception!',0 
	general_protection_msg:db 'General Protection Exception!',0 
	page_fault_msg:db 'Page Fault Exception!',0 
	x87_fpu_error_msg:db 'x87 FPU Floating-Point Error!',0 
	alignment_check_msg:db 'Alignment Check Exception!',0 
	machine_check_msg:db 'Machine Check Exception!',0 
	simd_msg:db 'SIMD Floating-Point Exception!',0  
	unknown_msg:db 'Unknown Interrupt!',0  

	intr_err_code:db 'Error Code:',0  
	intr_err_addr:db 'Error Address:',0  

	error_code_str: ;to store conversion result  
		.prefix: db '0x' 
		.str_buf:times 10 db 0  

	eip_addr_str: ;error address 
		.prefix:db '0x' 
		.str_buf:times 10 db 0 
